// 系統设置
var SYSCONF = {
    lang: 'zh',
    index_url:'/service-center/index.html'
};

// 国际化语言命名空间
var LANG = {};

// 工具类命名空间
var Ut = {};

// 共享模块
var shared = angular.module('servicecenter-shared', ['ngCookies','LocalStorageModule']);

// 系統常量设置
var SYSCONST = {
    /*kendo语言*/
    KENDO_LANG: 'zh-CN'
};


LANG.LOCAL_EN = {
    SYSNAME: 'Service Configuration Center',
    LOGIN:'LOGIN',
    PASSWORD:'Password',
    USER_NAME:'Username',
    MDYPWD:'Modify Password',
    LOGOUT:'Logout',
    OLD_PASSWORD:'Old Password',
    NEW_PASSWORD:'New Password',
    ENSURE_PASSWORD:'Confirm Password',
    CANCEL: 'Cancel',
    OK: 'OK',
    ZH:'Chinese',
    EN:'English',
    ERROR: 'Error',
    CONFIRM: 'Confirm? ',
    NORECORDS:'No data available.',
    FILTER: {
        info: "Filter Conditions",
        contains: 'contains',
        neq: 'Is not equal to',
        eq: 'Is equal to',
        and: 'and',
        or: 'or',
        filter: 'Filter',
        clear: 'clear',
        gte: 'Is greater than or equal to',
        lte: 'Is less than or equal to',
        gt: 'Is greater than',
        lt: 'Is less than',
        isnull: 'Is null',
        isnotnull: 'Is not null',
        after: 'Is after',
        before: 'Is before'
    },
    MODULE:{
        SERVICE_CENTER:{
            configServiceParam:'Configure Service Parameters',
            checkServiceStatus:'View Service Status',
            navigation:'Service/Application',
            release:'Release',
            released:'Released',
            unReleased:'Not released',
            releaseStatus:'Release Status',
            modifyItem:'Modified',
            modify:'Modified',
            publishSuccess:'Released successfully.',
            importConfig:'Import Config File',
            importSysServerConfig:'Import System Service Config',
            importFile:'Imported Configuration File:',
            scan:'Browse',
            exportConfig:'Export Config File',
            newItem:'Add',
            comment:'Remark',
            needRestart:'Restart (Y/N)',
            releaseTime:'Last Release Time',
            operator:'operation',
            yes:'Yes',
            no:'No',
            edit:'Edit',
            stop:'Stop',
            start:'Start',
            addEmsProxy:'Add EMS Proxy',
            emsProxySetting:'EMS Proxy Configuration',
            emsName: 'EMS Name',
            proxyServiceIp: 'Proxy Service IP',
            proxyServicePort: 'Proxy Service Port',
            u2kIP: 'EMS IP',
            u2kPort: 'EMS Port',
            u2kUserName: 'EMS Username',
            u2kPassword: 'EMS Password',
            status:'Status',
            serverName:'Service Name',
            serverIp:'Service IP',
            description:'Description',
            ems:'EMS',
            sync:'Synchronize',
            deleteEms:'Delete',
            batchRelease:'One-click Release',
            message: {
                required: 'This field cannot be null.',
                ip: 'Illegal IP address format',
                port: 'Illegal port input',
                portConflict: 'Port conflict',
                readEmsDataError: 'Failed to get EMS proxy configuration.',
                readSystemDataError: 'Failed to get system service configuration.',
                readDefaultDataError: 'Failed to get default configuration.',
                saveError: 'Saving failed.',
                delError: 'Deleting failed.',
                saveSuccess: 'Saved successfully.',
                syncError: 'Synchronizing failed.',
                STOPPED: 'Proxy service is stopped',
                AVAILABLE: 'Proxy service is running',
                RUNNING: 'Proxy service is Synchronizing data'
            },
            tip: {
                portFormatWrong: 'The port number format is incorrect.',
                emsPortRange: 'The port number ranges from 54351 to 54358.',
                u2kPortRange: 'The port number ranges from 0 to 65535.',
                jsonFormatWrong:'JSON file content format error',
                noSelect:'Please select the configuration before import.',
                containSpace: 'It cannot contain spaces.',
                empty: 'Cannot be null.',
                ipFormatWrong: 'The IP format is incorrect.',
                passwordLength: 'The password cannot exceed 16 characters.',
                syncEms:'Synchronizing….Please access to the service status window to view the data.',
                delSuccess: 'Deleted successfully.',
                noEms:'Please add the EMS proxy before release. ',
                deleteConfirmation: 'Are you sure you want to delete the EMS Proxy?'
            }
        }
    },
    TIP: {
        t1: 'Please enter the query key word.',
        t2: 'Please select the NE to be queried.',
        t3: 'Please enter the username and password.',
        t4: 'Please enter the username.',
        t5: 'Please enter the password.',
        t6: 'Please enter the new password.',
        t7: 'Please enter the old password.',
        t8: 'Please enter confirm the password.',
        t9: 'The passwords entered twice are not the same. ',
        t10: 'The password should be 8 to 16 characters and contain at least one number and one letter.',
        t11: 'The password is modified successfully.',
        t12: 'Drag the column head here to sort by that column',
        t13: 'The number of tasks cannot exceed 50.',
        t14: 'Please gather statistics before export. ',
        t15: 'Your browser does not support Websocket and therefore the reporting service may fail to run. Please upgrade your browser.',
        t16: 'The new password cannot be the same as the old password.',
        t17: 'Please query before export. ',
        t18: 'The domain is modified. Do you want to update it?',
        t19: 'The start date cannot be later than the end date.',
        t20: 'Please select NE statistics.',
        t21: 'Please select at least one threshold-crossing type.',
        t22: 'Please select at least one threshold-crossing level.',
        t23: 'The start time should not be later than the current time.',
        t24: 'Obtaining the object tree failed.',
        t25: 'Unable to create/modify the task.',
        t26: 'You can compare four ports at most.',
        t27: 'The number of NEs cannot exceed ',
        t28: 'Please select a logical domain to be queried.',
        t29: 'Download failed. Please confirm whether this report exists.',
        t30: 'You can compare four logical domains at most.',
        t31: 'The configuration is modified. Do you want to update it?',
        t32: 'The NE is deleted.',
        t33: 'The ONU performance collection status has changed.',
        t34: 'The manually entered mailbox format is incorrect. Multiple mailboxes should be separated by semicolons.',
        t35: 'Please fill in the recipient.',
        t36: 'Please fill in the ONU weak optical power ratio threshold.',
        t37: 'You can fill in no more than 30 recipients.',
        t38: 'Make sure there is at least one column of information to be displayed.',
        t39: 'Please select the alarm object.',
        t40: 'Failed to get the object tree. It cannot be queried',
        t41: 'Please select at least one NE',
        t42: 'The maximum statistical time period should not exceed 3 years.',
        t43: 'Be sure to enter the correct start and end time.'
    },
    ERR_Msg: {
        hostCheck: 'Please enter a valid IP address. ',
        taskNameEmpty: 'Please enter a task name.',
        nameLong: 'The task name cannot exceed 64 characters.',
        objEmpty: 'Please select an NE.',
        exportFieldEmpty: 'Please select the fields to be exported.',
        taskNameDuplicate: 'The task name already exists.',
        execTimeEmpty: 'Please enter the valid period of the task.',
        statsTimeEmpty: 'Please enter the task statistical time. ',
        timeOut: 'The task execution time should be within 180 days.',
        single_endTimeOut: 'The end time for statistics of a single task cannot be later than yesterday.',
        single_timeOut: 'The statistical time range for a single task cannot exceed 180 days.',
        timeFormatWrong: 'The date format is incorrect.',
        FTPTest: 'The FTP detection selected failed: ',
        selectFTP: 'Please set the FTP option.',
        opTimeCheck: 'Make sure the end time is later than the start time.',
        opTimeMinCheck: 'Make sure the start time selected is in the available range.',
        opTimeMaxCheck: 'Make sure the end time selected is in the available range.',
        getDataFailure: 'Obtaining data failed.',
        serverError: 'Background service error.',
        logoutFailure: 'Logout failed. Please try again or contact the administrator.',
        noPermission: 'You have not authorities to access this module.',
        noLogin: 'You have not logged in or the login has expired.',
        netError: 'Network exception. Please log in again.',
        timesMuch: 'The account will be locked after five consecutive password attempts.',
        timeOverNow: 'The time cannot be later than the current time.'
    },
    // 业务逻辑自己处理的errorCode
    ERR_CODE: {
        P03B00101: 'Username or password error.',
        P03B00104: 'Username or password error. The account will be locked after 5 consecutive password attempts.',
        P03B00102: 'You have tried too many times. Please try again later.',
        P03B00112: 'The old password is incorrect.',
        P03B00113: 'The old password is incorrect. The account will be locked after 5 consecutive password attempts.',
        B00012: 'License alarm.',
        P03B00100: 'The username already exists.',
        P03B00111: 'Can not delete online user.',
        P03B00120: 'The domain name already exists.',
        P03B00130: 'The domain does not exist.',
        A01B00100: 'The report task name already exists.',
        A01B00014: 'Updating the license file failed.',
        A01B00110: 'Duplicate FTP server name.',
        A01B00120: 'The FTP server is in use.',
        A01B00031: 'The query object does not exist.',
        A01S00110: 'FTP server connection failure.'
    },
    BTN_NAME: {
        b1: 'Back to Homepage',
        b2: 'Re-login'
    }
};

LANG.LOCAL_ZH = {
    SYSNAME: '服务配置中心',
    LOGIN:'登录',
    PASSWORD:'密码',
    USER_NAME:'用户名',
    MDYPWD:'修改密码',
    LOGOUT:'注销',
    OLD_PASSWORD:'旧密码',
    NEW_PASSWORD:'新密码',
    ENSURE_PASSWORD:'确认密码',
    CANCEL: '取消',
    OK: '确定',
    ZH:'中文',
    EN:'英文',
    ERROR: '哦哟，异常了...',
    CONFIRM: '确定吗？',
    NORECORDS:'没有数据',
    FILTER: {
        info: "过滤条件：",
        contains: '包含',
        neq: '不等于',
        eq: '等于',
        and: '且',
        or: '或',
        filter: '过滤',
        clear: '清除',
        gte: '大于等于',
        lte: '小于等于',
        gt: '大于',
        lt: '小于',
        isnull: '无数据',
        isnotnull: '有数据',
        after: '晚于',
        before: '早于'
    },
    MODULE:{
        SERVICE_CENTER:{
            configServiceParam:'配置服务参数',
            checkServiceStatus:'查看服务状态',
            navigation:'服务/应用',
            release:'发布',
            released:'已发布',
            unReleased:'未发布',
            releaseStatus:'发布状态',
            modifyItem:'修改',
            modify:'有修改',
            publishSuccess:'发布成功',
            importConfig:'导入配置文件',
            importSysServerConfig:'导入系统服务配置',
            importFile:'导入的配置文件:',
            scan:'浏览',
            exportConfig:'导出配置文件',
            newItem:'新增',
            comment:'备注',
            needRestart:'是否需要重启',
            releaseTime:'最后发布时间',
            operator:'操作',
            yes:'是',
            no:'否',
            edit:'编辑',
            stop:'停止',
            start:'启动',
            addEmsProxy:'新增EMS代理',
            emsProxySetting:'EMS代理设置',
            emsName: 'EMS名称',
            proxyServiceIp: '代理服务IP',
            proxyServicePort: '代理服务端口',
            u2kIP: '网管IP',
            u2kPort: '网管端口',
            u2kUserName: '网管用户名',
            u2kPassword: '网管密码',
            status:'状态',
            serverName:'服务名称',
            serverIp:'服务IP',
            description:'描述',
            ems:'EMS代理',
            sync:'同步',
            deleteEms:'删除',
            batchRelease:'一键发布',
            message: {
                required: '不能为空',
                ip: 'IP地址格式不合法',
                port: '端口输入不合法',
                portConflict: '端口已占用',
                readEmsDataError: '获取EMS代理配置数据失败！',
                readSystemDataError: '获取系统服务配置数据失败！',
                readDefaultDataError: '获取默认配置数据失败！',
                saveError: '保存失败！',
                delError: '删除失败！',
                saveSuccess: '保存成功！',
                syncError: '同步失败！',
                STOPPED: '服务未启动',
                AVAILABLE: '服务运行中',
                RUNNING: '正在同步数据'
            },
            tip: {
                portFormatWrong: '端口号格式不正确',
                emsPortRange: '端口号范围为54351~54358',
                u2kPortRange: '端口号范围为0~65535',
                jsonFormatWrong:'JSON文件内容格式错误',
                noSelect:'请选择配置后再导入',
                containSpace: '不能包含空格',
                empty: '不能为空',
                ipFormatWrong: 'IP格式不正确',
                passwordLength: '密码长度不能超过16字符',
                syncEms:'正在进行同步，请到服务状态页面查看。',
                delSuccess: '删除成功',
                noEms:'请添加EMS代理后再发布。',
                deleteConfirmation: '确定要删除该EMS代理吗？'
            }
        }
    },
    TIP: {
        t1: '请输入查询关键字',
        t2: '请选择要查询的网元',
        t3: '请输入用户名密码',
        t4: '请输入用户名',
        t5: '请输入密码',
        t6: '请输入新密码',
        t7: '请输入旧密码',
        t8: '请输入确认密码',
        t9: '两次密码不一致',
        t10: '密码长度为8-16字符，且至少包含一个数字和字母',
        t11: '密码修改成功',
        t12: '拖拽需要分组查看列的表头到此处',
        t13: '任务数量不能超过50个',
        t14: '请先统计后再导出',
        t15: '您的浏览器不支持Websocket，上报服务可能无法正常运行，请更新浏览器版本',
        t16: '新密码不能等于旧密码',
        t17: '请先查询后再导出',
        t18: '管理域已经变更，是否更新？',
        t19: '开始时间需不晚于结束时间',
        t20: '请选择网元统计',
        t21: '请至少选择一个越限类型',
        t22: '请至少选择一个越限级别',
        t23: '开始时间需不晚于当前时间',
        t24: '对象树获取失败',
        t25: '无法新建/修改任务',
        t26: '最多只能比较4个端口',
        t27: '网元个数不能超过',
        t28: '请选择要查询的逻辑域',
        t29: '下载失败，请确认该文件是否存在。',
        t30: '最多只能比较4个逻辑域',
        t31: '配置已经变更，是否更新？',
        t32: '当前网元已删除',
        t33: 'ONU性能采集状态已经变更。',
        t34: '手动输入的邮箱格式错误,多个邮箱请用分号间隔。',
        t35: '请填写收件人',
        t36: '请填写ONU弱光比门限',
        t37: '收件人不能超过30个',
        t38: '确保至少有一列信息展示',
        t39: '请选择告警对象',
        t40: '对象树获取失败，无法查询',
        t41: '请至少选择一个网元',
        t42: '最大统计时间段不得超过3年',
        t43: '请务必输入正确的开始、结束时间'
    },
    ERR_Msg: {
        hostCheck: '请输入格式正确的IP地址！',
        taskNameEmpty: '请输入任务名',
        nameLong: '任务名长度不能超过64字符',
        neEmpty: '请选择网元',
        domainEmpty: '请选择逻辑域',
        exportFieldEmpty: '请选择导出字段',
        taskNameDuplicate: '已存在该任务名',
        execTimeEmpty: '请输入任务有效期',
        statsTimeEmpty: '请输入任务统计时间',
        timeOut: '任务有效期建议在180天内',
        single_endTimeOut: '单次任务统计截止时间不能超过昨天',
        single_timeOut: '单次任务统计时间不能超过180天',
        timeFormatWrong: '您手动输入的时间不在可选范围内或格式不正确',
        FTPTest: '您选择的FTP检测失败：',
        selectFTP: '请设置FTP选项',
        opTimeCheck: '请确定您选择的结束时间大于开始时间！',
        opTimeMinCheck: '请确定您选择的开始时间在可选范围内',
        opTimeMaxCheck: '请确定您选择的结束时间在可选范围内',
        getDataFailure: '获取数据失败',
        serverError: '后台服务异常',
        logoutFailure: '注销失败，请重新尝试或联系管理员',
        noPermission: '抱歉，您没有权限访问该模块',
        reportDelay: '报表正在导出，是否跳转至报表日期归档页面查看导出情况？',
        noLogin: '抱歉，您还未登录或登录已经过期',
        netError: '网络异常，请重新尝试登录',
        timesMuch: '，连续5次密码错误，账户将被锁定',
        timeOverNow: '时间不能超过现在'
    },
    // 业务逻辑自己处理的errorCode
    ERR_CODE: {
        P03B00101: '用户名或密码错误',      //{{errorMsg}}形式显示在页面上
        P03B00104: '用户名或密码错误，连续5次密码错误，账户将被锁定', //{{errorMsg}}形式显示在页面上
        P03B00102: '尝试次数过多，请稍后再试',//{{errorMsg}}形式显示在页面上
        P03B00112: '旧密码错误',           //{{errorMsg}}形式显示在页面上
        P03B00113: '旧密码错误，连续5次密码错误，账户将被锁定',   //{{errorMsg}}形式显示在页面上
        B00012: 'license告警',            //登录成功后先弹框再跳转到index.html
        P03B00100: '用户名已存在',         //tip显示
        P03B00111: '在线用户不能删除',      //tip显示
        P03B00120: '管理域名称已存在',      //tip显示
        P03B00130: '管理域不存在',         //tip显示
        A01B00100: '报表任务名已存在',      //tip显示
        A01B00014: 'license文件更新失败',  //tip显示
        A01B00110: 'FTP服务器名重复',      //tip显示
        A01B00120: 'FTP服务器正在被使用',   //tip显示
        A01B00031: '查询对象不存在',        //tip显示
        A01S00110: 'FTP服务器连接失败'     //tip显示
    },
    BTN_NAME: {
        b1: '返回首页',
        b2: '重新登录',
        b3: '更新License',
        b4: '查看License信息',
        b5: '是',
        b6: '否'
    }
};
/**
 * 系统初始化操作
 */

//1.根据配置设置系统语言
var I18N = LANG['LOCAL_' + SYSCONF.lang.toUpperCase()];

//kendo 国际化设置
if (SYSCONF.lang === 'zh' && window.kendo) {
    kendo.culture('zh-CN');
}

/**
 * 导航指令
 */
shared.directive('fErrormessage', function () {
    return {
            restrict: 'E',
            template: ' <span  class="k-widget k-tooltip k-tooltip-validation k-invalid-msg" >' + '<span class="k-icon k-warning"> </span><span ng-transclude></span></span>',
            transclude: true,
            replace: true
        };
});
/**
 * Created by zhout3517 on 2017-6-7.
 * 控制表格过滤行显示/隐藏 ng指令
 */
shared.directive('fFilterBtn', ['$http', '$templateCache', function ($http, $templateCache) {
    return {
        restrict: 'E',
        template: $templateCache.get('filter.html'),
        scope: {
            gridFor: '@'
        },
        replace: true,
        link: function (scope, element, attrs) {
            //国际化
            scope.i18n = I18N.FILTER;
            // 过滤行控制按钮点击事件
            scope.filterBtnClkEvt = function (ele) {
                var gridElement = ele||angular.element('#' + scope.gridFor);
                var filterRowShow = gridElement.hasClass('filterRow');

                var newHeight = gridElement.innerHeight();
                var otherElements = gridElement.children().not('.k-grid-content');
                //61表示过滤行height为61px，当过滤行css改变时该数值可能也需要改变
                var otherElementsHeight = filterRowShow ? -61 : 61;

                otherElements.each(function () {
                    otherElementsHeight += $(this).outerHeight();
                });
                gridElement[filterRowShow ? 'removeClass' : 'addClass']('filterRow');
                gridElement.children('.k-grid-content').height(newHeight - otherElementsHeight);
            };
        }
    };
}]);

shared.service('AuthorityService', ['$q', '$http', 'URLService', '$cookies', function ($q, $http, URLService, $cookies) {
    this.setRole = function (role) {
        var roleJson = JSON.stringify(role);
        $cookies.put('role', roleJson, {path: '/'});
    };

    this.getRole = function () {
        var role = $cookies.get('role');
        return role ? JSON.parse(role) : null;
    };

    this.removeRole = function () {
        $cookies.remove('role', {path: '/'});
    };

    this.check = function () {
        if (!this.isLogin()) {
            window.location = SYSCONF.index_url;
        }
    };

    this.quit = function () {
        var _this = this;
        var deferred = $q.defer();
        var url = URLService.getURL('logout');
        $http.post(url).success(function (res) {
            if (res.success) {
                _this.removeRole();
                deferred.resolve();
            } else {
                deferred.reject();
            }
        });
        return deferred.promise;
    };

    this.isLogin = function () {
        return !!this.getRole();
    };
}]);
/**
 * http网络错误统一处理
 */
shared.factory('httpErrorInterceptor', ['$cookies', 'localStorageService', function ($cookies, localStorageService) {

    var httpErrorInterceptor = {
        request: function (config) {
            // 除.html(模板)结尾的请求外禁止缓存（$http.get方法会出现缓存）
            if (!config.url.endWith('.html')) {
                config.url += ('?bust=' + (new Date()).getTime());
            }
            return config;
        },
        response: function (res) {
            //angular-ui-router加载view模板也会进到response，此时返回的是模板字符串。
            if (angular.isObject(res.data)) {
                //1.正常响应(success == true)，由业务逻辑处理
                if (res.data.success) {
                    return res;
                }

                var errorCode = res.data.errorCode;
                //2.在I18N中注册了的errorCode(可能是全errorCode，也可能是errorCode的后6位)，由业务逻辑自己处理。
                if (I18N.ERR_CODE[errorCode] || (errorCode && I18N.ERR_CODE[errorCode.substring(3)])) {
                    return res;
                }

                //3.访问拦截
                // if (accessInterceptor(errorCode)) {
                //     //页面进行跳转，跳出函数
                //     return;
                // }

                //6.统一处理业务异常
                if (res.data.errorLevel === 'BIZ') {
                    Ut.dialog.warn(res.data.errorMsg, I18N.OK);
                    return res;
                } else if (res.data.errorLevel === 'SYS') {
                    //7.统一处理系统异常
                    Ut.dialog.errMsg(res.data.errorMsg);
                    return res;
                }

            } else {
                return res;
            }

        },
        requestError: function (e) {
            return e;
        },
        responseError: function (e, b) {
            if (e.status === 401) {
                //登录过期
                Ut.dialog.warn(I18N.ERR_Msg.noLogin, I18N.BTN_NAME.b2, function () {
                    setTimeout(function () {
                        $cookies.put('historyUrl', window.location.href, {path: '/'});
                        //清除role
                        $cookies.remove('role', {path: '/'});
                        window.location.href = SYSCONF.index_url;
                    }, 500);
                });
            } else {
                console.error('请求出现错误,status：' + e.status + ',statusText:' + e.statusText + ',data:' + e.data);
                return e;
            }
        }
    };

    return httpErrorInterceptor;

    //访问拦截
    function accessInterceptor(errorCode) {
        //1.登录过期
        if (errorCode && errorCode.endWith('S00011')) {
            Ut.dialog.warn(I18N.ERR_Msg.noLogin, I18N.BTN_NAME.b2, function () {
                setTimeout(function () {
                    $cookies.put('historyUrl', window.location.href, {path: '/'});
                    //清除role
                    $cookies.remove('role', {path: '/'});
                    window.location.href = SYSCONF.index_url;
                }, 500);
            });
            return true;
        }

        //2.没有权限
        if (errorCode && errorCode.endWith('S00010')) {
            Ut.dialog.warn(I18N.ERR_Msg.noPermission, I18N.BTN_NAME.b1, function () {
                setTimeout(function () {
                    window.location.href = SYSCONF.index_url;
                }, 500);
            });
            return true;
        }

        //3.license失效: A01B00010为license过期，A01B00011为网元数超过license限制,A01B00013为license无效
        // if (errorCode && (errorCode.endWith('B00010') || errorCode.endWith('B00011') || errorCode.endWith('B00013'))) {
        //     localStorageService.set('license', true);
        //     Ut.dialog.warn(res.data.errorMsg, I18N.BTN_NAME.b3, function () {
        //         setTimeout(function () {
        //             window.location.href = SYSCONF.nginx_licenseUrl;
        //         }, 500);
        //     });
        //     return true;
        // }

        return false;
    }
}]);

shared.factory('URLService', function () {
    var head = "";
    // var head = "http://10.170.120.57:7300/mock/5aa7675f919d410cb47f1524";
    // var head = "http://10.168.17.68:8080";

    var urlMap = {
        login: '/service-center/login',
        token: '/service-center/token',
        modifyPassword: '/service-center/modifyPassWord',
        logout: '/service-center/logout',

        getApps: '/service-center/getApps',
        getConfigData: '/service-center/getItems',
        updateConfigData: '/service-center/updateItemValue',
        publishConfig: '/service-center/publishConfig',

        readEmsProxy: '/service-center/getEmsConfig',
        addEmsConfig: '/service-center/addEmsConfig',
        updateEmsConfig: '/service-center/updateEmsConfig',
        deleteEmsConfig: '/service-center/deleteEmsConfig',
        syncEms: '/service-center/syncEms',
        publishEms: '/service-center/publishEms',

        importConifg: '/service-center/importConifgData',
        exportConfig: '/service-center/exportConifgData',
        batchRelease: '/service-center/publishAll',

        serverStatusInfo: '/service-center/queryStaticServerInfo'
    };

    return {
        getURL: function (name) {
            return head + urlMap[name];
        }
    }
});
angular.module('servicecenter-shared').run(['$templateCache', function($templateCache) {$templateCache.put('filter.html','<button class="btn btn-default btn-filter" ng-click="filterBtnClkEvt()"><i class="iconfont">&#xe629;</i>{{i18n.filter}}</button>');}]);
Ut.dialog = {
    tip: function (msg, callback) {
        swal({title: '', text: msg, allowOutsideClick: false}, callback);
    },
    warn: function (msg, btnname, callback) {
        swal({
            title: '',
            text: msg,
            type: 'warning',
            confirmButtonColor: '#DD6B55',
            confirmButtonText: btnname,
            closeOnConfirm: true
        }, callback);
    },
    errMsg: function (msg) {
        swal({title: I18N.ERROR, text: msg, type: "error", confirmButtonText: I18N.OK});
    },
    confirm: function (msg, callback) {
        swal({
            title: I18N.CONFIRM,
            text: msg,
            type: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#DD6B55',
            cancelButtonText: I18N.CANCEL,
            confirmButtonText: I18N.OK,
            closeOnConfirm: false, //warning: 此项配置为false可能会导致选择“是”弹出框关不掉的情况，必须在“是”的callback里调用swal再弹一个。 -by ldzhu
            closeOnCancel: true
        }, callback);
    },
    choose: function (msg,confirmButtonText,cancelButtonText,confirmCallback,cancelCallback) {
        swal({
            title:'',
            text: msg,
            type: 'success',
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            confirmButtonText: confirmButtonText,
            cancelButtonText: cancelButtonText,
            closeOnConfirm: true,
            closeOnCancel: true
        }, function (isConfirm) {
            if (isConfirm) {
                confirmCallback();
            } else {
                cancelCallback();
            }
        });
    }
};
Ut.IPUtils = {

    /**
     * 判断是否为IPV6地址
     * @returns {string}
     */
    isIPv6: function (str) {
        return /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^:((:[0-9a-fA-F]{1,4}){1,6}|:)$|^[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,5}|:)$|^([0-9a-fA-F]{1,4}:){2}((:[0-9a-fA-F]{1,4}){1,4}|:)$|^([0-9a-fA-F]{1,4}:){3}((:[0-9a-fA-F]{1,4}){1,3}|:)$|^([0-9a-fA-F]{1,4}:){4}((:[0-9a-fA-F]{1,4}){1,2}|:)$|^([0-9a-fA-F]{1,4}:){5}:([0-9a-fA-F]{1,4})?$|^([0-9a-fA-F]{1,4}:){6}:$/i.test(str);
    },
    /**
     * 判断是否为IPV4地址
     * @returns {string}
     */
    isIPv4: function (str) {
        return /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/i.test(str);
    },

    /**
     * 判断端口号是否合法
     * @param str
     * @returns boolean
     */
    port: function (str) {
        return /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/.test(str);
    }


};
Ut.strUtils = {
    isEmpty: function (str) {
        if (str === null || str === undefined || str === 'undefined' || (typeof str === 'string' && str.trim() === '')) {
            return true;
        } else {
            return false;
        }

    },
    isMailFormat: function (str) {
        return /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(str);
    },
    /**
     * case 1115931：由于kendo.toString在转换成百分比格式时，乘法直接采用原始数据*100，造成误差，导致kendo.toString(0.00195,'p2')结果为0.19%;
     * 因此将所有手动调用kendo.toString的地方用Ut.strUtils.toString方法代替
     */
    toString: function (value, format) {
        var result;
        //若定义了格式和数据
        if (angular.isDefined(format) && angular.isNumber(value)) {
            //解析格式类型
            var formatToArr = format.split('');
            var formatType = formatToArr[0];
            //若定义的格式是 百分比类型
            if (formatType === 'p') {
                var precision;
                precision = angular.isDefined(formatToArr[1]) ? formatToArr[1] : '';
                result = kendo.toString(Ut.calculateUtils.accMul(value, 100), 'n' + precision) + '%';
            } else {
                result = kendo.toString(value, format);
            }
        } else {
            result = kendo.toString(value, format);
        }
        return result;
    }
};
Ut.urlUtils = {
    getRootPath: function () {
        var origin = location.protocol + '//' + this.getHostAndPort() + '/service-center/';
        return origin;

        // TODO
        /*var origin = location.protocol + '//' + location.hostname + ':' + location.port;
         var pathName = location.pathname;
         var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
         var rootPath = origin + projectName + '/';
         return rootPath;*/
    },

    getHostAndPort: function () {
        var port = '';
        if (location.port) {
            port = ':' + location.port;
        }
        return window.location.hostname + port;
    },

    openUrl: function (url) {
        // case 1081580: 在FF中\不会被当成/，而会转成‘_’ --ldzhu
        url = url.replace(/\\/g, '/');
        // TODO dev
        url = this.getRootPath() + url;
        // url = 'http://10.168.17.68:8080/service-center/' + url;

        //截取文件名
        var strArr = url.split(/\//g);
        var fileName = strArr[strArr.length - 1];

        $.ajax({
            url: url,
            type: 'GET',
            xhrFields: {
                responseType: 'blob'
            },
            dataType: 'binary',
            success: function (data) {
                var blob = new Blob([data], {type: "application/octet-stream"});
                //兼容IE浏览器
                if (window.navigator.msSaveOrOpenBlob) {
                    window.navigator.msSaveOrOpenBlob(blob, fileName);
                } else {
                    //火狐、chrome浏览器通过a标签进行下载
                    var a = document.createElement("a");
                    a.id = 'exppub';
                    //保证pdf和html文件不在浏览器中打开，而是下载
                    a.download = fileName;
                    a.href = URL.createObjectURL(blob);
                    document.body.appendChild(a);
                    var alink = document.getElementById('exppub');
                    alink.click();
                    alink.parentNode.removeChild(a);
                }
            },
            error: function () {
                Ut.dialog.tip(I18N.TIP.t29);
            }
        });
    },

    // 将dataURL转化为Blob类型，常用于canvas绘图相关
    dataURLtoBlob: function (dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {type: mime});
    }
};
Array.prototype.remove = function (dx) {
    if (isNaN(dx) || dx > this.length) {
        return false;
    }
    for (var i = 0, n = 0; i < this.length; i++) {
        if (this[i] != this[dx]) {
            this[n++] = this[i];
        }
    }
    this.length -= 1;
};

//字符串以str开头
String.prototype.startWith = function (str) {
    var reg = new RegExp('^' + str);
    return reg.test(this);
};
//字符串以str结尾
String.prototype.endWith = function (str) {
    var reg = new RegExp(str + '$');
    return reg.test(this);
};